﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla;
using Csla.Data;
using System.Data;
using System.Data.Common;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

namespace Asah.SiteWorx.SiteMap
{
    [Serializable()]
    public class PageList : Csla.ReadOnlyListBase<PageList, PageInfo>
    {

        # region Factory Methods

        public static PageList GetPageList()
        {
            return DataPortal.Fetch<PageList>();
        }

        public static List<PageInfo> GetPublicPageList()
        {
            PageList list = PageList.GetPageList();
            List<PageInfo> publicList = new List<PageInfo>();

            var result = from page in list
                         where page.Visibility == PageVisibility.Public
                         select page;
            
            foreach (PageInfo info in result)
            {
                    publicList.Add(info);
            }

            return publicList;
        }

        public static PageInfo GetPageInfo(int pageId)
        {
            PageList pageList = DataPortal.Fetch<PageList>(new SingleCriteria<PageList, int>(pageId));
            PageInfo pageInfo = null;

            if (pageList.Count > 0)
            {
                pageInfo = pageList.Items[0];
            }
            return pageInfo;
        }

        public static PageInfo GetPageInfo(string path)
        {
            string fileName = path.ToString().Substring(path.ToString().LastIndexOf("/") + 1,
                              path.ToString().Length - path.ToString().LastIndexOf("/") - 1);

            PageList pageList = DataPortal.Fetch<PageList>(new SingleCriteria<PageList,String>(fileName));
            PageInfo pageInfo = null;

            if (pageList.Count > 0)
            {
                pageInfo = pageList.Items[0];
            }
            return pageInfo;
        }

        private PageList()
        {
            // require use of factory methods
        }

        #endregion

        #region Data Access

        private void DataPortal_Fetch()
        {
            Database db = DatabaseFactory.CreateDatabase("SiteWorx");
            DbCommand dbCommand = db.GetStoredProcCommand("aspnet_SiteMap_GetPages");
            db.AddInParameter(dbCommand, "ApplicationId", DbType.Guid, Site.GetSite().ApplicationId);

            try
            {
                using (var dr = new SafeDataReader(db.ExecuteReader(dbCommand)))
                {
                    RaiseListChangedEvents = false;
                    IsReadOnly = false;

                    while (dr.Read())
                    {
                          PageInfo info = new PageInfo(dr.GetInt32("PageId"), dr.GetString("Title"), dr.GetString("FileName"), 
                                                 dr.GetString("Url"), dr.GetString("MetaKeywords"), dr.GetString("MetaDescription"), 
                                                 dr.GetString("MenuText"), dr.GetString("MenuHoverText"), dr.GetBoolean("DisplayInMenu"), 
                                                 dr.GetInt32("MenuPosition"), dr.GetString("MasterPage"), (PageVisibility)dr.GetInt32("Visibility"), 
                                                 dr.GetInt32("ParentPageId"), dr.GetGuid("CreatedBy"), dr.GetSmartDate("CreatedDate"), 
                                                 dr.GetGuid("LastUpdatedBy"), dr.GetSmartDate("LastUpdatedDate"));
                          this.Add(info);
                    }
                    IsReadOnly = true;
                    RaiseListChangedEvents = true;
                }
            }
            catch (Exception ex)
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Layer Policy");
                if (rethrow)
                {
                    throw;
                }
            }

        }

        private void DataPortal_Fetch(SingleCriteria<PageList, int> criteria)
        {
            Database db = DatabaseFactory.CreateDatabase("SiteWorx");
            DbCommand dbCommand = db.GetStoredProcCommand("aspnet_SiteMap_GetPage");
            db.AddInParameter(dbCommand, "ApplicationId", DbType.Guid, Site.GetSite().ApplicationId);
            db.AddInParameter(dbCommand, "PageId", DbType.Int32, criteria.Value);

            try
            {
                using (var dr = new SafeDataReader(db.ExecuteReader(dbCommand)))
                {
                    RaiseListChangedEvents = false;
                    IsReadOnly = false;

                    while (dr.Read())
                    {
                        PageInfo info = new PageInfo(dr.GetInt32("PageId"), dr.GetString("Title"), dr.GetString("FileName"),
                                               dr.GetString("Url"), dr.GetString("MetaKeywords"), dr.GetString("MetaDescription"),
                                               dr.GetString("MenuText"), dr.GetString("MenuHoverText"), dr.GetBoolean("DisplayInMenu"),
                                               dr.GetInt32("MenuPosition"), dr.GetString("MasterPage"), (PageVisibility)dr.GetInt32("Visibility"),
                                               dr.GetInt32("ParentPageId"), dr.GetGuid("CreatedBy"), dr.GetSmartDate("CreatedDate"),
                                               dr.GetGuid("LastUpdatedBy"), dr.GetSmartDate("LastUpdatedDate"));
                        this.Add(info);
                    }
                    IsReadOnly = true;
                    RaiseListChangedEvents = true;
                }
            }
            catch (Exception ex)
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Layer Policy");
                if (rethrow)
                {
                    throw;
                }
            }

        }

        private void DataPortal_Fetch(SingleCriteria<PageList, string> criteria)
        {
            Database db = DatabaseFactory.CreateDatabase("SiteWorx");
            DbCommand dbCommand = db.GetStoredProcCommand("aspnet_SiteMap_GetPageByFileName");
            db.AddInParameter(dbCommand, "ApplicationId", DbType.Guid, Site.GetSite().ApplicationId);
            db.AddInParameter(dbCommand, "FileName", DbType.String, criteria.Value);

            try
            {
                using (var dr = new SafeDataReader(db.ExecuteReader(dbCommand)))
                {
                    RaiseListChangedEvents = false;
                    IsReadOnly = false;

                    while (dr.Read())
                    {
                        PageInfo info = new PageInfo(dr.GetInt32("PageId"), dr.GetString("Title"), dr.GetString("FileName"),
                                               dr.GetString("Url"), dr.GetString("MetaKeywords"), dr.GetString("MetaDescription"),
                                               dr.GetString("MenuText"), dr.GetString("MenuHoverText"), dr.GetBoolean("DisplayInMenu"),
                                               dr.GetInt32("MenuPosition"), dr.GetString("MasterPage"), (PageVisibility)dr.GetInt32("Visibility"),
                                               dr.GetInt32("ParentPageId"), dr.GetGuid("CreatedBy"), dr.GetSmartDate("CreatedDate"),
                                               dr.GetGuid("LastUpdatedBy"), dr.GetSmartDate("LastUpdatedDate"));
                        this.Add(info);
                    }
                    IsReadOnly = true;
                    RaiseListChangedEvents = true;
                }
            }
            catch (Exception ex)
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Layer Policy");
                if (rethrow)
                {
                    throw;
                }
            }

        }

        #endregion

    }
}
